#!/bin/bash
###############################################################################
#       脚本名称: test_utils_number.sh
#       功能描述: 数字处理工具(utils_number.sh)单元测试
#       作者: 林再来
#       日期: 2025-10-20
#       版本: 1.0
#       功能:
#           1、测试数字处理工具的所有核心功能
#           2、验证数字验证、格式化、运算、比较等功能
#           3、确保数字处理工具的独立性和正确性
###############################################################################

# 切换到脚本目录
cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1

# 加载测试框架
source ../test_framework.sh

# 加载被测模块
source ../../../scripts/utils/utils_number.sh

# 创建临时测试目录
TEST_DIR=$(create_test_dir)

###############################################################################
# 测试用例
###############################################################################

# 测试: 数字验证函数
test_utils_number_validation() {
    assert_true "整数验证应该正确" "utils_number_is_integer '123'"
    assert_false "浮点数不应该被识别为整数" "utils_number_is_integer '123.45'"
    assert_false "字符串不应该被识别为整数" "utils_number_is_integer 'abc'"
    
    assert_true "浮点数验证应该正确" "utils_number_is_float '123.45'"
    assert_false "整数不应该被识别为浮点数" "utils_number_is_float '123'"
    assert_false "字符串不应该被识别为浮点数" "utils_number_is_float 'abc'"
    
    assert_true "正数验证应该正确" "utils_number_is_positive '5'"
    assert_false "负数不应该被识别为正数" "utils_number_is_positive '-5'"
    assert_false "零不应该被识别为正数" "utils_number_is_positive '0'"
    
    assert_true "负数验证应该正确" "utils_number_is_negative '-5'"
    assert_false "正数不应该被识别为负数" "utils_number_is_negative '5'"
    assert_false "零不应该被识别为负数" "utils_number_is_negative '0'"
    
    assert_true "零验证应该正确" "utils_number_is_zero '0'"
    assert_false "正数不应该被识别为零" "utils_number_is_zero '5'"
    assert_false "负数不应该被识别为零" "utils_number_is_zero '-5'"
}

# 测试: 数字范围检查
test_utils_number_range_check() {
    if utils_number_in_range '5' '1' '10'; then
        echo "✓ 范围内数字检查应该通过"
    else
        echo "✗ 范围内数字检查应该通过"
        return 1
    fi
    
    if ! utils_number_in_range '15' '1' '10'; then
        echo "✓ 范围外数字检查应该失败"
    else
        echo "✗ 范围外数字检查应该失败"
        return 1
    fi
    
    if utils_number_in_range '1' '1' '10'; then
        echo "✓ 边界值检查应该通过"
    else
        echo "✗ 边界值检查应该通过"
        return 1
    fi
    
    if utils_number_in_range '10' '1' '10'; then
        echo "✓ 边界值检查应该通过"
    else
        echo "✗ 边界值检查应该通过"
        return 1
    fi
}

# 测试: 数字格式化
test_utils_number_formatting() {
    local result=$(utils_number_format_thousands "1234567")
    assert_equals "1,234,567" "$result" "千分位格式化应该正确"
    
    local result=$(utils_number_format_thousands "-1234567")
    assert_equals "-1,234,567" "$result" "负数千分位格式化应该正确"
    
    local result=$(utils_number_format_precision "3.14159" 2)
    assert_equals "3.14" "$result" "精度格式化应该正确"
    
    local result=$(utils_number_to_percentage "0.25" 1)
    assert_equals "25.0%" "$result" "百分比转换应该正确"
    
    local result=$(utils_number_to_scientific "1234.56" 2)
    assert_contains "$result" "e+03" "科学计数法转换应该正确"
}

# 测试: 数学运算
test_utils_number_arithmetic() {
    local result=$(utils_number_add "10" "5")
    assert_equals "15" "$result" "加法运算应该正确"
    
    local result=$(utils_number_subtract "10" "3")
    assert_equals "7" "$result" "减法运算应该正确"
    
    local result=$(utils_number_multiply "4" "5")
    assert_equals "20" "$result" "乘法运算应该正确"
    
    local result=$(utils_number_divide "15" "3")
    # 检查结果是否接近5（考虑浮点数精度）
    if [[ "$result" =~ ^5\.0*$ ]] || [[ "$result" = "5" ]] || [[ "$result" = "5.0000000000" ]]; then
        echo "✓ 除法运算应该正确"
    else
        echo "✗ 除法运算应该正确: 期望5，实际'$result'"
        return 1
    fi
    
    local result=$(utils_number_power "2" "3")
    assert_equals "8" "$result" "幂运算应该正确"
    
    local result=$(utils_number_sqrt "16")
    # 检查结果是否接近4（考虑浮点数精度）
    if [[ "$result" =~ ^4\.0*$ ]] || [[ "$result" = "4" ]] || [[ "$result" = "4.0000000000" ]]; then
        echo "✓ 平方根运算应该正确"
    else
        echo "✗ 平方根运算应该正确: 期望4，实际'$result'"
        return 1
    fi
}

# 测试: 数字比较
test_utils_number_comparison() {
    utils_number_compare "5" "3"
    assert_equals "1" "$?" "5应该大于3"
    
    utils_number_compare "3" "5"
    assert_equals "2" "$?" "3应该小于5"
    
    utils_number_compare "5" "5"
    assert_equals "0" "$?" "5应该等于5"
    
    local result=$(utils_number_max "1" "5" "3" "9" "2")
    assert_equals "9" "$result" "最大值应该正确"
    
    local result=$(utils_number_min "1" "5" "3" "9" "2")
    assert_equals "1" "$result" "最小值应该正确"
}

# 测试: 随机数生成
test_utils_number_random() {
    # 测试随机整数生成
    local result=$(utils_number_random_int "1" "10")
    if utils_number_in_range "$result" "1" "10"; then
        echo "✓ 随机整数应该在范围内"
    else
        echo "✗ 随机整数应该在范围内: $result"
        return 1
    fi
    
    # 测试随机浮点数生成
    local result=$(utils_number_random_float "1.0" "10.0" 2)
    if utils_number_in_range "$result" "1.0" "10.0"; then
        echo "✓ 随机浮点数应该在范围内"
    else
        echo "✗ 随机浮点数应该在范围内: $result"
        return 1
    fi
}

# 测试: 进制转换
test_utils_number_base_conversion() {
    local result=$(utils_number_dec_to_bin "10")
    assert_equals "1010" "$result" "十进制转二进制应该正确"
    
    local result=$(utils_number_bin_to_dec "1010")
    assert_equals "10" "$result" "二进制转十进制应该正确"
    
    local result=$(utils_number_dec_to_hex "255")
    assert_equals "ff" "$result" "十进制转十六进制应该正确"
    
    local result=$(utils_number_hex_to_dec "ff")
    assert_equals "255" "$result" "十六进制转十进制应该正确"
    
    # 测试负数
    local result=$(utils_number_dec_to_bin "-5")
    assert_equals "-101" "$result" "负数十进制转二进制应该正确"
}

# 测试: 统计函数
test_utils_number_statistics() {
    local result=$(utils_number_sum "1" "2" "3" "4" "5")
    assert_equals "15" "$result" "求和应该正确"
    
    local result=$(utils_number_average "1" "2" "3" "4" "5")
    assert_equals "3" "$result" "平均值应该正确"
    
    local result=$(utils_number_abs "-5")
    assert_equals "5" "$result" "绝对值应该正确"
    
    local result=$(utils_number_abs "5")
    assert_equals "5" "$result" "正数绝对值应该正确"
    
    local result=$(utils_number_round "3.14159" 2)
    assert_equals "3.14" "$result" "四舍五入应该正确"
}

# 测试: 错误处理
test_utils_number_error_handling() {
    # 测试无效输入
    local output=$(utils_number_add "abc" "5" 2>&1)
    assert_contains "$output" "参数不是有效数字" "无效输入应该报错"
    
    local output=$(utils_number_divide "10" "0" 2>&1)
    assert_contains "$output" "除数不能为零" "除零应该报错"
    
    local output=$(utils_number_sqrt "-4" 2>&1)
    assert_contains "$output" "负数不能计算平方根" "负数开方应该报错"
    
    local output=$(utils_number_random_int "10" "5" 2>&1)
    assert_contains "$output" "最小值不能大于最大值" "范围错误应该报错"
    
    local output=$(utils_number_bin_to_dec "abc" 2>&1)
    assert_contains "$output" "参数不是有效的二进制格式" "无效二进制应该报错"
}

# 测试: 边界情况
test_utils_number_edge_cases() {
    # 测试零值
    local result=$(utils_number_add "0" "0")
    assert_equals "0" "$result" "零加零应该等于零"
    
    local result=$(utils_number_multiply "5" "0")
    assert_equals "0" "$result" "任何数乘以零应该等于零"
    
    # 测试大数
    local result=$(utils_number_add "999999999" "1")
    assert_equals "1000000000" "$result" "大数加法应该正确"
    
    # 测试小数
    local result=$(utils_number_add "0.1" "0.2")
    # 注意：由于浮点数精度问题，这里可能需要特殊处理
    assert_not_empty "$result" "小数加法应该返回结果"
}

# 测试: 浮点数精度
test_utils_number_precision() {
    local result=$(utils_number_format_precision "3.14159265359" 3)
    assert_equals "3.142" "$result" "高精度格式化应该正确"
    
    local result=$(utils_number_divide "1" "3" 5)
    assert_contains "$result" "0.33333" "高精度除法应该正确"
}

# 测试: 特殊数字处理
test_utils_number_special_cases() {
    # 测试科学计数法输入
    local result=$(utils_number_is_number "1.23e+02")
    # 注意：当前实现可能不支持科学计数法，这里主要测试不报错
    assert_not_empty "$result" "科学计数法处理应该不报错"
    
    # 测试负数
    local result=$(utils_number_format_thousands "-1234567")
    assert_equals "-1,234,567" "$result" "负数格式化应该正确"
    
    # 测试小数
    local result=$(utils_number_format_thousands "1234.56")
    assert_equals "1,234.56" "$result" "小数千分位格式化应该正确"
}

###############################################################################
# 运行测试
###############################################################################

echo "========================================"
echo "测试套件: 数字处理工具 (utils_number.sh)"
echo "========================================"

# 运行所有测试
run_test "数字验证函数" test_utils_number_validation
run_test "数字范围检查" test_utils_number_range_check
run_test "数字格式化" test_utils_number_formatting
run_test "数学运算" test_utils_number_arithmetic
run_test "数字比较" test_utils_number_comparison
run_test "随机数生成" test_utils_number_random
run_test "进制转换" test_utils_number_base_conversion
run_test "统计函数" test_utils_number_statistics
run_test "错误处理" test_utils_number_error_handling
run_test "边界情况" test_utils_number_edge_cases
run_test "浮点数精度" test_utils_number_precision
run_test "特殊数字处理" test_utils_number_special_cases

echo "----------------------------------------"
echo "测试套件 [数字处理工具 (utils_number.sh)] 完成"
echo "----------------------------------------"
